home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / VGOSHADO.ZIP / VGOSHADO.TXT < prev   
Text File  |  1997-06-13  |  30KB  |  611 lines

  1.  
  2. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  3.  
  4.   VGOSHADO.TXT - Realtime Shadow FAQ.                
  5.  
  6. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  7.  
  8.         Written by:  Vector/Vertigo (Brian Cowan)
  9.              Email:  cowan@gold.guate.net
  10.   Vertigo Web Page:  http://demoscene.interstat.net/~vertigo/
  11.  
  12.   irc:   #coders #vertcode
  13.  
  14.   Revision history:
  15.  
  16.   10/06/97      v0.70Beta - Awesome tips from MidNight, touched up the doc
  17.   04/06/97      v0.60Beta - Added the tips section with help from Statix
  18.   01/06/97      v0.50Beta - A few typo fixes and a cool tip from Statix
  19.   30/05/97      v0.10Beta - Initial version
  20.  
  21. ─────────────────────────────────────────────────────────────────────────────
  22.  INTRODUCTION
  23. ─────────────────────────────────────────────────────────────────────────────
  24.  
  25. Well, for the last 2 months or so I have been laying around the
  26. house, forcing my brain to try and come up with the perfect shadow
  27. algorithm, an algorithm that works beautifully in hardware as well as
  28. software. An algo that adds almost no overhead to the actual
  29. rendering, and yields perfect results on any surface with any type of
  30. lighting... And all of this of course real-time.
  31.  
  32. I am not just talking about those dinky shadows that are cast onto
  33. the floor like a black blob, or the shape of a few enemies/items. I
  34. mean a fully immersive experience, where all of the light is obscured
  35. in a sewer, except for the few slits from the grates above. Or light
  36. volumes that fall through a stained glass window will color the
  37. objects that pass behind with all the beautiful colors of the glass.
  38. Your mouth must be watering for this algo...
  39.  
  40. Nope, couldn't come up with one =). But I have noticed one thing, the
  41. net (particularly the demoscene) always tends to find all the coolest
  42. real- time graphical techniques before anything else. So why not make
  43. a doc explaining all I could find and come up with about the subject,
  44. and maybe everyone will work together and we will overcome the pain
  45. of these monotonous 3D worlds and find the perfect technique yet... 
  46.  
  47. ─────────────────────────────────────────────────────────────────────────────
  48.  YOU HAVE DEPRESSED ME, TELL ME SOMETHING GOOD
  49. ─────────────────────────────────────────────────────────────────────────────
  50.  
  51. Oh, sorry about that. No, all is not lost at the moment. There are
  52. several shadow techniques that are tried and true, and yield very
  53. impressive results. In fact some daring demos have had this effect
  54. for quite some time, like Machines of Madness/Dubius, or some other
  55. old one I can't remember with a flatshaded 'hollow' cube. But the one
  56. that comes most to mind is Spotlite/Funk, and is in fact another
  57. thing that inspired me to write this doc in the first place.
  58.  
  59. So what I will try to explain here are the techniques I think these
  60. demos used, plus a few others I found/came up with that may have good
  61. potential depending upon the scene. I will also give a sort of
  62. rating/summary to each technique dealing with:
  63.  
  64.  - Its complexity to code
  65.  - Overall visual appeal
  66.  - Speed for low poly scenes
  67.  - Speed for high poly scenes
  68.  - Good for hardware
  69.  - Pros and cons
  70.  
  71. And anything else my mind that is overloaded with Pepsi decides to
  72. come up with =).
  73.  
  74. ─────────────────────────────────────────────────────────────────────────────
  75.  BEFORE WE BEGIN
  76. ─────────────────────────────────────────────────────────────────────────────
  77.  
  78. This doc does assume you have good knowledge of 3D, Volumes, and
  79. rasterizers. If you can't get a Z-Buffered Gouraud Textured triangle
  80. going, or 3D clipping and such, then I advise you go have fun, learn,
  81. drink some Pepsi, and come back later.
  82.  
  83. Finally, this doc does not deal with soft shadows (although with some
  84. algos, they can be 'faked'). Nor does it deal with pre-generated
  85. shadows through cached Texture maps. I also do not mention a bunch of
  86. other shadow algorithms that I saw no chance of working real-time
  87. (ray tracing) or were crap in the first place. Check out the
  88. reference section for some places where you can get info on these.
  89.  
  90. Now, for the good stuff... (presented in what is IMO worst to best,
  91. but read them all).
  92.  
  93. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  94.                             * THE ALGORITHMS *
  95. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  96.  
  97. ─────────────────────────────────────────────────────────────────────────────
  98.  LIGHT VOLUME SUBDIVISION
  99. ─────────────────────────────────────────────────────────────────────────────
  100.  
  101. Technically, what you do in this algorithm is define a 'web' of light
  102. volumes. These volumes are created by forming a cone of each polygon
  103. against a light, where one end  is capped by the polygon, and the
  104. other end can stretch to infinity, or preferably end at some distance
  105. (then any polygons beyond this distance do not need to be processed).
  106.  
  107. The cones are formed by an amount of quads equal to the number of
  108. sides in the poly, so a triangle would be formed by 3 quads, where
  109. the tangent to each quadrilateral edge goes in the direction of the
  110. light ray against the edge of the tri.
  111.  
  112. Now after you have all these volumes, you clip every tri against them,
  113. to find out if they are in a shadow or not. Remember to clip
  114. recursively, or you can't get shadows in the middle of tris.
  115.  
  116. Right now you must think that this is *REALLY* fucking slow, which is
  117. true, but thankfully there are quite a few speedups and enhancements
  118. you can take advantage of.
  119.  
  120. First of all, it comes in handy to not make a volume for every
  121. polygon, but to do it for every surface facing the light. So for
  122. example, a sphere made out of tris, You would make a big volume
  123. formed by the whole sphere facing the light, with a bunch of quads
  124. lining the edge. Be warned though, doing this surface building is
  125. rather tricky, and requires a good form of representing the mesh
  126. ('Winged edge' should do nicely). 
  127.  
  128. And another immediately apparent thing is that you can sort the polys
  129. front to back, so then you don't need to check polys against the
  130. volumes of polys that are in back of them (in the light, not the
  131. view).
  132.  
  133. Another speedup is to actually project the polys onto a 'virtual'
  134. light screen, then you can do a check to see what polys are visible
  135. to the light.  However, doing this check will only work for
  136. spotlights, eliminating one of the most useful things of this
  137. technique, unless you are willing to do multiple projections.
  138.  
  139. Something very nice about this technique is that it only needs to be
  140. done once for a scene if the objects/lights don't move, You can fly
  141. around and see it from anywhere. Plus it accommodates multiple light
  142. sources very easily, and can handle light volumes passing through
  143. stained glass window if you add flags to the polys for it.
  144.  
  145.  Complexity    =  75%
  146.  Visual appeal =  95%
  147.  Low poly      =  60%
  148.  High poly     =  15%
  149.  Hardware      =  98%
  150.  
  151. Pros - Only needed to be built once for static scenes. Much room to
  152.        expand on this technique. Easy multiple light sources. Without
  153.        projection method will handle point light sources. Handles stained
  154.        glass window.  Best for hardware, fits nicely into most 3D engines.
  155.  
  156. Cons - Don't let all the pros sway you, this algo is *SLOOOW*, (but can
  157.        still sometimes be done real-time). Don't use for high poly scenes,
  158.        since the amount of work is squared to the amount of polys.
  159.  
  160. ─────────────────────────────────────────────────────────────────────────────
  161.  LIGHT VOLUME RASTERIZATION
  162. ─────────────────────────────────────────────────────────────────────────────
  163.  
  164. This technique is a quick dirty approach to doing shadow volumes,
  165. that will probably look very crappy if done in a complex scene, but
  166. is still a nice hack anyways ;)
  167.  
  168. What you do here, is divide the polygons into 'surfaces' that are
  169. facing the light, and project quads that fall off the edges of the
  170. surface (see above.)  After that, for each quad, give it a flag if it
  171. is facing the viewer or not.
  172.  
  173. After this, the method is very straightforward. Simply sort the polys
  174. back to front, and include the lighting quads into this sorting list.
  175. Then rasterize these quads just like all the other polys. If the quad
  176. is one of the ones that is facing away from you, then make everything
  177. behind it lighter if its one of the ones facing to you, then make
  178. everything behind it darker.
  179.  
  180. This should ideally make every poly inside the shadow volume dark,
  181. and even out everything outside the volume to the normal color (maybe
  182. even leaving a cool shadow halo because of error acumulation =).
  183.  
  184. However this is one of those ideas I got watching a repeat of
  185. "Married With Children" (ARGH! Why did they cancel that, Kelly was
  186. cute! =). So actually implemented it probably looks like crap. But on
  187. a few very small tests I did with a small amount of polys, it did
  188. look acceptable.
  189.     BTW, I guess I should mention the drawbacks to this method. First
  190. off, the scene obviously must be Z-Buffered. Also, you must have a
  191. perfect sorting algorithm for this, or else the transparent polys
  192. will overlay something behind, and it will look interesting to say
  193. the least ;). Or do what I do (If zbuffer available) And draw the
  194. transparent polys after the original rendering.
  195.   Finnally, the shadows cant be that deep, because when you reach an away
  196. shadow plane, if you add 20  to 250 (saturated), it will come to 256, but
  197. when you subtract because of the facing you shadow plane, it will not be
  198. the original 250, it will be 236.
  199.  
  200.  Complexity    =  45%
  201.  Visual appeal =  35%
  202.  Low poly      =  90%
  203.  High poly     =  35%
  204.  Hardware      =  95%
  205.  
  206. Pros - Simple, intuitive, quick and dirty. Easy multiple light sources,
  207.        very easy translucent surfaces, leaves a pretty little 'shadow
  208.        halo'.
  209.  
  210. Cons - Probably looks like crap in a real scene. Needs good/weird sorting.
  211.        Will only work with very soft shadows, or else saturation will make
  212.        everything really crappy. Really Ad-Hoc algo.
  213.  
  214. ─────────────────────────────────────────────────────────────────────────────
  215.  MULTIPLE BITMAP PROJECTION
  216. ─────────────────────────────────────────────────────────────────────────────
  217.  
  218. This is a nice easy way of doing shadows. Basically what you do here:
  219.  
  220.         - Have a base light map. Phong maps work well here.
  221.         - Form groups of polys into surfaces facing the light (see above.)
  222.         - Order these surfaces front-back for the light
  223.         - For each surface:
  224.           + Find the coordinates that the texture projects onto each vert
  225.             (normal perspective projection works nicely =).
  226.           + Make a copy of the previous lightmap. Then draw the current
  227.             surface onto it as black (or even colored to do a stained glass
  228.             window effect.) You will then use this new texture for the next
  229.             surface.
  230.  
  231. Now you may notice, what happens if the texture is tiled across a
  232. poly?  Unfortunately you will have to make a new software tmapper
  233. that saturates the coordinates to 0 or MAX so that they don't
  234. overflow. However in hardware many cards have the option to do this
  235. automatically, and you can make a thin outline on the image that you
  236. can chroma-key, so that it is transparent (or use the texture as an
  237. alpha map in the first place).
  238.  
  239. Very simple but effective technique. I'm not quite sure if it will
  240. work as I have not seen it documented anywhere, but many thanks to
  241. the cool demo Robotnik/Rage for giving me the idea.
  242.  
  243. BTW, this is actually very crappy to do on hardware, because of the
  244. shear amount of texture loading to do would be immense. Which is a
  245. shame because of the saturation and chroma-key and all the other cool
  246. stuff hardware lets us do... However you can still use the mapping to
  247. do real neat spotlights and projections anyway, even without the
  248. shadows.
  249.    It is also worth noting that making accurate lighting with this
  250. method is very hard in (RGB) software. Since lighting is actually a function
  251. of the color * light, not an addition. So a texel of colour (0..1)
  252. 'r=.5 , g=1  , b=.5' and light intensities of 'rgb=.5' should actually give
  253. 'r=.25, g=.5 , b=.5'... and this is without counting specularity.
  254. Hardware has the ability to do this at no cost, and you can do it easily if
  255. you use paletted textures or a paletted video mode. 
  256. You can however do a quick hack in software that does look convincing.
  257. although won't allow pure blacks or whites. Simply shift the src and dest
  258. pixels right by 1, AND the final bits of RGB off (for 32bit it would be
  259. AND 7F7F7F7Fh) and add them together.
  260.  
  261.  Complexity    =  20%
  262.  Visual appeal =  70%
  263.  Low poly      =  70%
  264.  High poly     =  60% (Slow if many surfaces,not polys)
  265.  Hardware      =  20%                                                  
  266.  
  267. Pros - Fast and easy for software. Lights can have really cool shapes (like
  268.        logos, or movie projectors). Translucent objects can make colored
  269.        shadows at almost no performance cost.
  270.  
  271. Cons - Very slow for hardware because of all the texture loading...
  272.        hopefully AGP will help us out a bit. *LOTS OF MEMORY* needed, but
  273.        unfortunately keeping the lightmaps small will give a lot of point
  274.        sampling artifacts. Multiple lights are a bitch. AGP + hardware
  275.        bilinear aliasing and multiple passes should help all these problems.
  276.        Can only do spotlight with one pass.
  277.  
  278. ─────────────────────────────────────────────────────────────────────────────
  279.  TWO PASS Z-BUFFER SHADOWS
  280. ─────────────────────────────────────────────────────────────────────────────
  281.  
  282. These are perhaps the most well known, tried and true types of
  283. shadows.  They are fast, speed varies almost linearly with the amount
  284. and size of polys. And are incredibly easy.
  285.  
  286. What you do for this algorithm is simple, just draw a Z-Buffer of the
  287. world from the light's point of view. Then for the actual camera view
  288. at the rasterizing stage, grab the coords of each vertex in light
  289. space (XYZ), and interpolate them much like texture mapping. At each
  290. pixel, do a check of the interpolated light Z with the Z found in the
  291. light Z buffer at the interpolated light X and Y. If it's behind,
  292. then it's in shadow. As you see, this is almost exactly like normal
  293. Z-Buffering, except the Z-Buffer grid position is taken from the
  294. interpolated light's X/Y, instead of the pixel plotting position.
  295.  
  296. This shadow method can definitely be done real-time, The demo Spotlite
  297. by Funk proves this method. However it is very hard to get going
  298. fast if you want to support and arbitrary number of lights. You can
  299. also go a step further and make 'soft shadows' by including an
  300. intensity value with the light Z-Buffer, and use this as an alpha
  301. blend/lightness factor. Finally, the Light Z-Buffer interpolations
  302. ideally should be done with perspective correction, although this is
  303. something you may try skipping, especially if you are doing multiple
  304. lights.
  305.  
  306. This algo can be found in most good 3D books if you want more
  307. information on it. Also, you can always do the Z-Buffer compares per
  308. pixel if this is a non-real-time application and its a very high poly
  309. scene. Also, make sure your camera can render to different size
  310. canvases, to be able to render the light-view scene in a 256*256
  311. window (recommended) for fast Z-Buffer location finding.
  312.  
  313. Unfortunately, Z-Buffers have a very bad aliasing artifact problem.
  314. Shadows can look very pixelated if the difference beetween surfaces
  315. is large enough.  Also, this can cause polys that are at a sharp
  316. angle to actually occlude themselves. Statix told me a very
  317. interesting way of solving the later problem though, where you store
  318. the average of the 2 nearest points in the Z-Buffer. This way, the
  319. point is to far to oclude itself, but to near as to not oclude polys
  320. that are behind. Unfortunately, I do not know a fast way of finding
  321. these nearest points.
  322.  
  323.  Complexity    =  25%
  324.  Visual appeal =  75%
  325.  Low poly      =  60%
  326.  High poly     =  70% 
  327.  Hardware      =  Impossible                                                  
  328.  
  329.  
  330. Pros - Very fast and easy for software. 'Tried in combat'. Lights can
  331.        have really cool shapes, and faked soft shadows. Low memory
  332.        consumption.
  333.  
  334. Cons - Impossible to do on current hardware (maybe not on programmable
  335.        chipsets though). No 'true' translucency since depth for back objects
  336.        is lost. Support for an arbitrary amount of lights is very hard.
  337.        Since the Light Z-Buffer may be to small, aliasing artifacts can
  338.        easily arise.
  339.  
  340.  
  341. ─────────────────────────────────────────────────────────────────────────────
  342.  TWO PASS S-BUFFER METHOD
  343. ─────────────────────────────────────────────────────────────────────────────
  344.  
  345. A perhaps interesting variation of the above method that I thought
  346. of, is the two Pass S-Buffer. If it actually works, It may turn out
  347. to be the fastest overall of the methods I have presented in this
  348. document. If you don't know what S-Buffers are, make shure to grab
  349. Paul Nettle's (Midnight) tutorial off of Hornet on them. Before you even
  350. attempt these, make sure you have fast S-Buffer insertion routines.
  351.  
  352. First, build a normal S-Buffer for the camera. Then for each light,
  353. build a span list as viewed from it. *BUT* you have to either rotate
  354. the light so that the X axis aligns with the X axis of the view, or
  355. build the spans at an angle. ;)
  356.  
  357. By now, I think you know what we are going to do =). For each span in
  358. the light view, convert to view space and place into the according
  359. position into the view S-Buffer list. Then doing a normal S-Buffer
  360. compare, find if the spans or parts of them fall behind the current
  361. span. If they do, then simply replace the spans under them (splitting
  362. if necessary) with a shadow tag. Then when you render the spans, just
  363. do a check to see if they are in shadow or not.
  364.  
  365. You should also note that you obviously do not need to rasterize the
  366. light spans, only build the span list. Also, this algo should handle
  367. multiple lights with extreme ease. Of course the spans that you
  368. replace with shadow versions don't need their deltas recalculated or
  369. anything. Plus if you have knowledge about the hardware and how it
  370. handles deltas, you can do 1 pixel high tris to simulate spans, and
  371. feed it the pre-calculated deltas. If not, hope the hardware is fast
  372. enough to do all those spans anyway. =) It also may be advantageous
  373. to compare every view span to each light instead of the other way
  374. around.
  375.  
  376. I am still very sketchy on this method though... first of all, in
  377. many cases it will probably look quite incorrect because of
  378. perspective. The light X spans will almost never be equal to the
  379. camera X spans, no matter how you rotate. This isn't so noticeable in
  380. the Z-Buffer method because it encompasses a very small area, and can
  381. vary with each poly instead of the whole light view, plus perspective
  382. correction can be done with the zbuffer method to fix any
  383. innacuracies, but would be extremely weird and hard with the S-Buffer
  384. method, so for some light->view angles it may be better to resort to a
  385. different technique. If anyone gets this or a variation of it working,
  386. I would love to hear from them.
  387.  
  388.  Complexity    =  85% 
  389.  Visual appeal =  50%
  390.  Low poly      =  90%
  391.  High poly     =  80% 
  392.  Hardware      =  50%                                                  
  393.  
  394. Pros - Fast and elegant. Should fit into any S-Buffering engine very
  395.        nicely.  Handles multiple lights extremely fast and efficient. The
  396.        time taken to light a scene should be rather constant, no matter the
  397.        amount of polys. May have potential for improvement.
  398.  
  399. Cons - I thought of it, so it probably doesn't work =). Not tried
  400.        anywhere.  Shadows will probably 'flicker' a lot due to span aliasing
  401.        artifacts.  Will only work with spotlights. No 'true' translucent
  402.        objects casting color shadows.
  403.  
  404. ─────────────────────────────────────────────────────────────────────────────
  405.  POLYGON-ID BUFFER SHADOWS
  406. ─────────────────────────────────────────────────────────────────────────────
  407.  
  408. This method is by far my favorite of all here, and wouldn't exist if
  409. not for a great tip from MidNight. It's very similar to two pass
  410. Z-Buffer shadows, but is so much better I thought it deserved a
  411. section all its own.
  412.  
  413. All that you do here is sort the polys back to front like normal for
  414. the light. Then for each poly, simply 'flatshade' a unique poly id
  415. for it into a buffer (The 16 least significant bits of the tri PTR
  416. usually works well).
  417.  
  418. Then for the camera view, interpolate the triangle in light space
  419. just like the Z-Buffer method (except you DON'T need interpolate Z
  420. anymore). And then for each pixel, check to see if the ID in the
  421. light buffer is the same as the ID for the current poly. If it isn't,
  422. then the pixel is in shadow.
  423.  
  424. As you can see, this method is extremely fast, no need to interpolate
  425. Z for the light buffer in creation or checking!(Although you can
  426. always use Zbuffers if the scene has many sorting errors.) And it's
  427. actually MORE accurate than the dual Z-Buffer method, because polys
  428. can't shadow themselves. Also, this method can be very easily adapted to
  429. the two pass S-Buffer method.
  430.  
  431. As cool as this method is, it still has a few drawbacks... First of
  432. all, objects that are marked not to cast shadows will always be in
  433. shadow (if your engine offers that ability). However, objects that
  434. are marked not to receive shadows will still properly work.  Second,
  435. it is still very slow for an arbitrary amount of lights because of
  436. the light loop inside the inner (per- pixel) loop. But even with
  437. this, the method can definately be used for quite high poly worlds in
  438. real-time. =)
  439.  
  440.  Complexity    =  10%
  441.  Visual appeal =  90%
  442.  Low poly      =  90%
  443.  High poly     =  90% 
  444.  Hardware      =  Impossible                                                  
  445.  
  446. Pros - Fastest working one here. Even a kid could do it. Lights can
  447.        have really cool shapes, and faked soft shadows. Low memory
  448.        consumption.  No polys 'shadowing' themselves.
  449.  
  450. Cons - Impossible to do on current hardware (maybe not on
  451.        programmable chipsets though). No 'true' translucency since depth for
  452.        back objects is lost. Support for an arbitrary amount of lights is
  453.        very hard.  Since the light-buffer may be to small, aliasing
  454.        artifacts can easily arise.
  455.  
  456.  
  457. ─────────────────────────────────────────────────────────────────────────────
  458.  TIPS & TRICKS
  459. ─────────────────────────────────────────────────────────────────────────────
  460.  
  461. Before leaving this section, I'll put in some universal tricks that
  462. can give a tremendous speed boost to these methods.
  463.  
  464. - Don't program in Qbasic or Lingo ;)
  465.  
  466. - Statix reminded me to mention something very important. You can get
  467.   a tremendous speed boost if you use convex object. Not only for
  468.   shadows, but many other things (like collision detection is a breeze
  469.   with these.) How are these advantageous to shadows? First, they can
  470.   not shadow themselves.  Second, finding the edges of the object to
  471.   the light is very easy. You simply flag every edge for every visible
  472.   poly it has. If it has only 1 visible attached poly, then its an
  473.   edge. Third and most important for the Light buffer methods, a convex
  474.   object is a convex poly when projected =). So you just put the edges
  475.   into an edge list in any order you want, and fill with whatever that
  476.   buffer desires. Since they are convex objects, you don't need to
  477.   worry about filling the poly exactly... all you need to do is 'stay
  478.   beetween the lines' of the projected poly =). So now your 2000 tri
  479.   sphere is a piece of cake for the cpu to render for the light.
  480.   Obviously for the polygon-id buffer method, fill it with a shape ID,
  481.   and for the Zbuffer method, interpolate Z along the edges and inside.
  482.  
  483. - I will mention this again, as I can't stress it enough:  EXPERIMENT!
  484.   Every method has an almost infinite amount of variations, NO
  485.   algorithm is perfect.
  486.  
  487. - Flags are nice. Don't process objects that won't be affected in the
  488.   view (Unless its a one time technique). Remember you still need to
  489.   process the polys that project into the view volume though.
  490.  
  491. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  492.                            * THE LAST WORDS *
  493. ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
  494.  
  495. ─────────────────────────────────────────────────────────────────────────────
  496.  THE PERFECT SHADOW ALGORITHM
  497. ─────────────────────────────────────────────────────────────────────────────
  498.  
  499. As you can see, there are many working real-time shadow algorithms,
  500. each with its own specific strength and weakness. And all of them
  501. have endless variations. Unfortunately, none of them even comes close
  502. to being perfect.
  503.  
  504. To me, the perfect real-time shadow algorithm is one that:
  505.  
  506.    - It's *=FAST=*.
  507.    - Works in hardware as well as software.
  508.    - Can handle translucent as well as opaque surfaces.    
  509.    - Is precision perfect.
  510.    - Is not resolution dependant (speed or precision).
  511.    - Will work with multiple lights.
  512.    - Is not 'hardcoded' and fits nicely into a 3D engine pipeline.
  513.    
  514. Probably the closest algorithm to fill the above, is actually the
  515. current crappiest one. The light volume subdivision method. The good
  516. thing is that this method does have plenty of room for improvement,
  517. and I can see someone coming up with a fast way of doing it (or
  518. something similar) someday.
  519.  
  520. ─────────────────────────────────────────────────────────────────────────────
  521.  REFERENCES AND OTHER COOL STUFF
  522. ─────────────────────────────────────────────────────────────────────────────
  523.  
  524. First of all, I would like to name one book that has helped me
  525. tremendously in everything about 3D and graphics. It actually
  526. explains why and how most everything works:
  527.  
  528.    "Computer Graphics Principles and Practice"
  529.    Foley, vanDam, Feiner, Hughes
  530.    2nd Edition in C
  531.    ISBN: 0-201-84840-6
  532.  
  533. Another Book that is very good, and touches up on many parts that
  534. CGP&P skimps on a little is:
  535.  
  536.    "Advanced Animation and Rendering Techniques"
  537.    Mark & Alan Watt.
  538.    ISBN 0-201-54412-1
  539.  
  540. Many people like AART more than CGP&P, although I personally think
  541. that CGP&P is invaluable. Both books are by Addison-Wesley.
  542.  
  543. Also, make sure to check out Spotlight/Funk which I think uses the
  544. two pass Z-Buffer method; Robotnik/Rage which appears to use the
  545. multiple projected bitmap method or something like it; and Machines
  546. Of Madness, which looks like it uses the shadow volume clip method.
  547. They can all be found on hornet (ftp.cdrom.com/pub/demos/).
  548.  
  549. Finally, if you are not on IRC, make sure to get on! I have found
  550. many people on IRC an invaluable source of knowledge, and would
  551. probably still be stuck on a rotating flatshaded duck without them.
  552. ;)
  553.  
  554. ─────────────────────────────────────────────────────────────────────────────
  555.  CONCLUSION
  556. ─────────────────────────────────────────────────────────────────────────────
  557.  
  558. This document was not only written to help teach people, but to get
  559. feedback from the world on how to improve these methods. I am not real
  560. happy with any of them and hope that we can all work out a good way
  561. of doing it.
  562.  
  563. All the contributors to this doc have one thing to say, experiment
  564. and learn to think differently. All these methods have many
  565. variations, but in the end, maybe all these are "back-ass-ackwards"
  566. in the first place.
  567.  
  568. If you do have any method or improvement you would like to add to
  569. this document, please send it to me. You will be of course well
  570. acredited for it.  Also, I hope that in the next version I can
  571. include a decent working shadow engine with code so that everyone can
  572. examine. Unfortunately lately I just don't have time, and I wanted to
  573. get this thing out there because I didn't see any coming soon. Although
  574. (If there are any mesh artists out there willing to lend a hand in the
  575. group, please drop me a line!). But until then, I hope that I explained
  576. the methods well enough so that you don't need it. As always, feedback
  577. is much appreciated, and I will definitely try and respond to all emails.
  578. If you send any flames, please make them constructive =).
  579.  
  580. If you do use any algorithms in here, or found this doc useful,
  581. please email and tell me so. =) Its stuff like that that keeps people
  582. writing more docs in the first place. Of course some greets or
  583. acknowledgement would also be much appreciated. =)
  584.  
  585.                   With a frumple in one hand and a Pepsi in the other,
  586.                                                       - Vector/Vertigo
  587.  
  588. ─────────────────────────────────────────────────────────────────────────────
  589.  GREETS AND CREDITS
  590. ─────────────────────────────────────────────────────────────────────────────
  591.  
  592. Current contributors to the doc:
  593.  
  594.   Vector     -  (cowan@gold.guate.net)
  595.   Statix     -  (AJBE2@hermes.cam.ac.uk)
  596.   MidNight   -  (midnight@grafix3d.dyn.ml.org)
  597.  
  598. Greets:
  599.  
  600. Oh god I hate these, I always want to greet like 500 people (a la
  601. Faith =).  Ill keep it very short, that way everyone can be pissed at
  602. me instead of only a few people:
  603.  
  604.   TimJ (Frumple!), Jcl, sorry I forgot to put you in the last doc =),
  605.   Crow, Leviathan, Vastator,  MrData, Gaffer (NASM rocks!), submissive,
  606.   VOR, god, fysx, brazil, Grimace, deepee, Phred, Gooroo, PGM, Zog,
  607.   pGeist, Phoenix, fuzzy, Winghead, Pascal, You, Tachu!, Cuca, And
  608.   everyone else in Guatemala =).  Ok, greets are too long already...
  609.  
  610.   Byee!        
  611.